﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Configuration;
using System.Drawing;
using System.Drawing.Imaging;

namespace Sukul.PhotoTools.BL
{
    public sealed class FileMaster
    {
        #region ctor
        public FileMaster()
        {
            config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            section = (Sukul.PhotoTools.BL.Configuration.MediaConfigSection)config.GetSection("MediaSettingsGroup/MediaSettings");
            _photoFilters = section.Photo.Filter.ToLower().Split('|');
            _videoFilters = section.Video.Filter.ToLower().Split('|');
        }

        public FileMaster(string sourceFolder, string photoDestFolder, string videoDestFolder)
            : base()
        {
            _sourceFolder = sourceFolder;
            _photoDestFolder = photoDestFolder;
            _videoDestFolder = videoDestFolder;
        }
        #endregion

        #region Private Fields
        public static bool Cancel = false;
        private static System.Configuration.Configuration config;
        private static Sukul.PhotoTools.BL.Configuration.MediaConfigSection section;
        private static string _sourceFolder = string.Empty;
        private static string _photoDestFolder = string.Empty;
        private static string _videoDestFolder = string.Empty;
        private static int _itemProcessedCount = 0;
        private List<string> _files = new List<string>();
        private List<string> _skippedFiles = new List<string>();
        private string[] _photoFilters = null;
        private string[] _videoFilters = null;
        #endregion

        #region Events and Deletegates
        public delegate void del_Progress(object parent, string message, int processedItemCount, int totalItemCount, int skippedFilesCount);
        public event del_Progress FileCopy_Progress;
        #endregion

        public void SetFolders(string startFolder, string photoDestFolder, string videoDestFolder)
        {
            _sourceFolder = startFolder;
            _photoDestFolder = photoDestFolder;
            _videoDestFolder = videoDestFolder;
        }

        private static string getPhotoFilter()
        {
            return section.Photo.Filter;
        }

        private static string getVideoFilter()
        {
            return section.Video.Filter;
        }

        public void AnalyzeFiles()
        {
            // Search for photos
            foreach (var p in section.Photo.Filter.Split('|'))
            {
                if (Cancel)
                {
                    return;
                }
                _files.AddRange(Directory.GetFiles(_sourceFolder, "*." + p.ToLower(), SearchOption.AllDirectories).ToList());
            }

            // Search for videos
            foreach (var p in section.Video.Filter.Split('|'))
            {
                if (Cancel)
                {
                    return;
                }
                _files.AddRange(Directory.GetFiles(_sourceFolder, "*." + p.ToLower(), SearchOption.AllDirectories).ToList());
            }
        }

        /// <summary>
        /// Recursively processes the given file and all its subdirectories
        /// </summary>
        public void ProcessFiles()
        {
            string destFilename = string.Empty;
            string destPath = string.Empty;
            string destSubFolder = _photoDestFolder;
            DateTime fileDateCreated = DateTime.Now;
            string extension = string.Empty;
            bool isMatch = false;
            Image tmpImage = null;
            string sdate = string.Empty;
            string secondhalf = string.Empty;
            string firsthalf = string.Empty;

            _skippedFiles = new List<string>();
            Cancel = false;
            // Get a list of files to process
            AnalyzeFiles();
            foreach (var file in _files)
            {
                isMatch = false;
                extension = Path.GetExtension(file).Replace(".", String.Empty).ToLower();
                fileDateCreated = File.GetCreationTime(file);

                // Determine if the file goes into the video or photo directory
                if (_photoFilters.Contains(extension))
                {
                    try
                    {
                        tmpImage = Image.FromFile(file);
                        PropertyItem propItem = tmpImage.GetPropertyItem(36867);
                        //fileDateCreated//
                        //Convert date taken metadata to a DateTime object 
                        sdate = Encoding.UTF8.GetString(propItem.Value).Trim();
                        secondhalf = sdate.Substring(sdate.IndexOf(" "), (sdate.Length - sdate.IndexOf(" ")));
                        firsthalf = sdate.Substring(0, 10);
                        firsthalf = firsthalf.Replace(":", "-");
                        sdate = firsthalf + secondhalf;
                        fileDateCreated = DateTime.Parse(sdate);
                    }
                    catch
                    {
                        fileDateCreated = File.GetCreationTime(file);
                    }

                    destSubFolder = _photoDestFolder;
                    isMatch = true;
                }
                else if (_videoFilters.Contains(extension))
                {
                    fileDateCreated = File.GetCreationTime(file);
                    destSubFolder = _videoDestFolder;
                    isMatch = true;
                }

                if (!isMatch)
                {
                    // Skip the file if it is not in the extension filters
                    _skippedFiles.Add(file);
                }
                else
                {
                    // Do the work if the file needs to be copied
                    destPath = string.Format(@"{0}\{1}\{2}\{3}",
                                    destSubFolder,
                                    fileDateCreated.Year,
                                    new DateTime(DateTime.Now.Year, fileDateCreated.Month, 1).ToString("MMM"),
                                    fileDateCreated.Day);
                    destFilename = string.Format(@"{0}\{1}", destPath, Path.GetFileName(file));

                    if (!Directory.Exists(destPath.ToLower()))
                    {
                        Directory.CreateDirectory(destPath.ToLower());
                    }

                    if (!File.Exists(destFilename.ToLower()))
                    {
                        File.Copy(file, destFilename.ToLower());
                    }
                }

                // Cancel if the user has stopped the operation
                if (Cancel)
                {
                    return;
                }

                // Report progress
                _itemProcessedCount++;
                if (FileCopy_Progress != null)
                {
                    FileCopy_Progress(this, string.Format("Processing {0} out of {1}{2}Skipped: {3}", _itemProcessedCount, _files.Count, Environment.NewLine, _skippedFiles.Count),
                    _itemProcessedCount, _files.Count, _skippedFiles.Count);
                }
            }
        }
    }
}
